home *** CD-ROM | disk | FTP | other *** search
- //***************************************************************************
- //
- // this file is (c) '94-'96 Niklas Beisert
- //
- // this file is part of the cubic player development kit.
- // you may only use/modify/spread this file under the terms stated
- // in the cubic player development kit accompanying documentation.
- //
- //***************************************************************************
-
- //cp.ini
- //[sound]
- // playerdevices=devpSB
- //[devpSB]
- // link=devpsb
- // driver=_plrSoundBlaster
- // addprocs=_plrSBAdd
- // handle=1
- // sbrevstereo=off ;// some sb pros reverse stereo...
-
- // player sound device example
-
- #include <stdlib.h>
- #include <string.h>
- #include <dos.h>
- #include <ctype.h>
- #include <conio.h>
- #include "irq.h"
- #include "dma.h"
- #include "ss.h"
- #include "player.h"
-
- #define SS_SB_REVSTEREO 1
-
-
- extern "C" extern sounddevice plrSoundBlaster;
-
- static signed short sbPort;
- static signed char sbIRQ;
- static signed char sbDMA;
- static signed char sbDMA16;
- static signed char sbUseVer;
- static char rightirq;
-
- static unsigned char getcfg()
- {
- sbPort=-1;
- sbIRQ=-1;
- sbDMA=-1;
- sbDMA16=-1;
- sbUseVer=-1;
- char *s=getenv("BLASTER");
- if (!s)
- return 0;
- while (1)
- {
- while (isspace(*s))
- s++;
- if (!*s)
- break;
- switch (*s++)
- {
- case 'a': case 'A':
- sbPort=strtoul(s, 0, 16);
- break;
- case 'i': case 'I':
- sbIRQ=strtoul(s, 0, 10);
- break;
- case 'd': case 'D':
- sbDMA=strtoul(s, 0, 10);
- break;
- case 'h': case 'H':
- sbDMA16=strtoul(s, 0, 10);
- break;
- case 't': case 'T':
- sbUseVer=strtoul(s, 0, 10);
- switch (sbUseVer)
- {
- case 6: sbUseVer=4; break;
- case 2: case 4: sbUseVer=3; break;
- case 3: sbUseVer=2; break;
- case 1: sbUseVer=1; break;
- default: sbUseVer=-1;
- }
- break;
- }
- while (!isspace(*s)&&*s)
- s++;
- }
- return 1;
- }
-
- static unsigned char inpSB(unsigned char p)
- {
- return inp(sbPort+p);
- }
-
- static void outpSB(unsigned char p, unsigned char v)
- {
- outp(sbPort+p,v);
- }
-
- static void outSB(unsigned char v)
- {
- while (inpSB(0xC)&0x80);
- outpSB(0xC,v);
- }
-
- static unsigned char inSB()
- {
- while (!(inpSB(0xE)&0x80));
- return inpSB(0xA);
- }
-
- static void initSB()
- {
- outpSB(0x6,1);
- inpSB(0x6);
- inpSB(0x6);
- inpSB(0x6);
- inpSB(0x6);
- inpSB(0x6);
- inpSB(0x6);
- inpSB(0x6);
- inpSB(0x6);
- outpSB(0x6,0);
- }
-
- static void initSBp()
- {
- outpSB(0x6,1);
- delay(100);
- outpSB(0x6,0);
- delay(100);
- }
-
- static setrateSB(unsigned char r)
- {
- outSB(0x40);
- outSB(r);
- }
-
- static void resetSB()
- {
- inpSB(0xE);
- }
-
- static void resetSB16()
- {
- inpSB(0xF);
- }
-
- static void spkronSB()
- {
- outSB(0xD1);
- }
-
- static void spkroffSB()
- {
- outSB(0xD3);
- }
-
- static void writeMixer(unsigned char p, unsigned char v)
- {
- outpSB(0x4, p);
- outpSB(0x5, v);
- }
-
- static unsigned char readMixer(unsigned char p)
- {
- outpSB(0x4, p);
- return inpSB(0x5);
- }
-
- static void test()
- {
- rightirq=1;
- }
-
- static char testPort(unsigned short port, int delay)
- {
- sbPort=port;
- if (delay)
- initSBp();
- else
- initSB();
- int i;
- for (i=0; i<1000; i++)
- if (inpSB(0xE)&0x80)
- return inpSB(0xA)==0xAA;
- return 0;
- }
-
- static char testirq(unsigned char irq)
- {
- irqInit(irq, test, 0);
-
- initSB();
- setrateSB(0xD3);
-
- rightirq=0;
-
- outSB(0x80);
- outSB(0x03);
- outSB(0x00);
- for (unsigned short i=0; i!=0xFFFF; i++)
- if (rightirq)
- break;
-
- irqClose();
-
- initSB();
- resetSB();
-
- return rightirq;
- }
-
- static char testdma(unsigned char irq, unsigned char dma)
- {
- outp(0x0A,4);
- outp(0x0A,5);
- outp(0x0A,7);
-
- irqInit(irq, test, 0);
- dmaStart(dma, 0, 10, 0x48);
-
- initSB();
- setrateSB(0xD3);
-
- rightirq=0;
-
- outSB(0x14);
- outSB(0x03);
- outSB(0x00);
- for (unsigned short i=0; i!=0xFFFF; i++)
- if (rightirq)
- break;
- irqClose();
- dmaStop();
-
- initSB();
- resetSB();
-
- return rightirq;
- }
-
- static char testdma16(unsigned char irq, unsigned char dma)
- {
- outp(0x0A,4);
- outp(0x0A,5);
- outp(0x0A,7);
- outp(0xD4,5);
- outp(0xD4,6);
- outp(0xD4,7);
-
- irqInit(irq, test, 0);
- dmaStart(dma, 0, 2, 0x48);
-
- initSB();
- setrateSB(0xEA);
-
- rightirq=0;
-
- outSB(0xB6);
- outSB(0x10);
- outSB(0x00);
- outSB(0x00);
- for (unsigned i=0; i!=0xFFFF; i++)
- if (rightirq)
- break;
- irqClose();
- dmaStop();
-
- initSB();
- resetSB16();
-
- return rightirq;
- }
-
- static unsigned short getVersion()
- {
- outSB(0xE1);
- while(1)
- {
- unsigned char verhi=inSB();
- if (verhi==0xAA)
- continue;
- return ((unsigned short)verhi<<8)+inSB();
- }
- }
-
-
-
- static long playpos;
- static long buflen;
- static int lastpos=17977;
- static void (*playproc)();
- static int regengetpos()
- {
- int p=dmaGetBufPos();
- if (p==lastpos)
- {
- playproc();
- irqReInit();
- }
- lastpos=p;
- return p;
- }
-
- static void advance(int pos)
- {
- playpos+=(pos-(playpos%buflen)+buflen)%buflen;
- }
-
- static void sb1Player()
- {
- resetSB();
- outSB(0x14);
- outSB(0xFF);
- outSB(0xFF);
- }
-
- static void sb2proPlayerHS()
- {
- resetSB();
- outSB(0x91);
- }
-
- static void sb16Player8()
- {
- resetSB();
- outSB(0x45);
- }
-
- static void sb16Player16()
- {
- outSB(0x47);
- resetSB16();
- }
-
- static int sbRate;
- static unsigned char sbTimerConst;
- static unsigned char sbStereo;
- static unsigned char sb16Bit;
- static unsigned char sbSignedOut;
- static unsigned char revstereo;
- static __segment dmabufsel;
-
- static void sbSetOptions(int rate, int opt)
- {
- switch (sbUseVer)
- {
- case 1: case 2:
- opt&=~(PLR_STEREO|PLR_16BIT|PLR_SIGNEDOUT);
- break;
- case 3:
- opt&=~(PLR_16BIT|PLR_SIGNEDOUT);
- break;
- }
- if (revstereo)
- opt^=PLR_REVERSESTEREO;
- sbStereo=!!(opt&PLR_STEREO);
- sb16Bit=!!(opt&PLR_16BIT);
- sbSignedOut=!!(opt&PLR_SIGNEDOUT);
-
- unsigned long rt=rate;
- if ((sbUseVer==3)&&sbStereo)
- rt<<=1;
-
- if (rt<4000)
- rt=4000;
- if (sbUseVer==4)
- if (rt<5000)
- rt=5000;
- if ((sbUseVer==2)||(sbUseVer==3))
- if (rt<8000)
- rt=8000;
-
- if (rt>45454)
- rt=45454;
- if ((sbUseVer==2)||(sbUseVer==3))
- if (rt>43478)
- rt=43478;
- if ((sbUseVer==1))
- if (rt>22222)
- rt=22222;
-
- sbTimerConst=256-1000000/rt;
- rate=1000000/(256-sbTimerConst);
-
- if ((sbUseVer==3)&&sbStereo)
- rate>>=1;
-
- sbRate=rate;
- plrRate=rate;
- plrOpt=opt;
- }
-
- long muldiv64(long, long, long);
- #pragma aux muldiv64 parm [eax] [edx] [ecx] = "imul edx" "idiv ecx"
-
- static long gettimer()
- {
- return muldiv64(playpos+(dmaGetBufPos()-playpos%buflen+buflen)%buflen, 65536, sbRate<<(sbStereo+sb16Bit));
- }
-
- void memsetd(void *, long, int);
- #pragma aux memsetd parm [edi] [eax] [ecx] = "rep stosd"
-
- static int sbPlay(void *&buf, int &len)
- {
- buf=(unsigned char*)dmaAlloc(len, dmabufsel);
- if (!buf)
- return 0;
- memsetd(buf, (plrOpt&PLR_SIGNEDOUT)?0:(plrOpt&PLR_16BIT)?0x80008000:0x80808080, len>>2);
-
- initSBp();
- resetSB();
- resetSB16();
- setrateSB(sbTimerConst);
- setrateSB(sbTimerConst);
- spkronSB();
-
- switch (sbUseVer)
- {
- case 1:
- playproc=sb1Player;
- break;
- case 2: case 3:
- playproc=sb2proPlayerHS;
- break;
- case 4:
- playproc=sb16Bit?sb16Player16:sb16Player8;
- break;
- }
-
- irqInit(sbIRQ, playproc, 0);
- dmaStart(sb16Bit?sbDMA16:sbDMA, buf, len, 0x58);
-
- switch (sbUseVer)
- {
- case 1:
- outSB(0x14);
- outSB(0xFF);
- outSB(0xFF);
- break;
- case 2: case 3:
- outSB(0x48);
- outSB(0xFF);
- outSB(0xFF);
- outSB(0x91);
- if (sbUseVer==3)
- writeMixer(0xE, readMixer(0xE)&~2|(sbStereo?0x22:0x20));
- break;
- case 4:
- outSB(sb16Bit?0xB6:0xC6);
- outSB((sbStereo?0x20:0x00)|(sbSignedOut?0x10:0x00));
- outSB(0xFC);
- outSB(0xFF);
- break;
- }
-
- buflen=len;
- playpos=0;
- plrGetBufPos=regengetpos;
- plrGetPlayPos=regengetpos;
- plrAdvanceTo=advance;
- plrGetTimer=gettimer;
-
- return 1;
- }
-
- static void sbStop()
- {
- irqClose();
- dmaStop();
- initSBp();
- resetSB();
- resetSB16();
- dmaFree(dmabufsel);
- }
-
-
-
- static int sbInit(const deviceinfo &card)
- {
- if (!testPort(card.port, 1))
- return 0;
- resetSB();
- resetSB16();
-
- revstereo=!!(card.opt&SS_SB_REVSTEREO);
-
- sbPort=card.port;
- sbIRQ=card.irq;
- sbDMA=card.dma;
- sbDMA16=card.dma2;
- unsigned char ver=getVersion()>>8;
- if (card.subtype==-1)
- sbUseVer=ver;
- else
- sbUseVer=card.subtype;
- if (sbUseVer>ver)
- return 0;
- if ((sbUseVer==3)&&(ver==4))
- return 0;
-
- /*
- if (!testirq(sbIRQ))
- return 0;
- if (!testdma(sbIRQ, sbDMA))
- return 0;
- if (sbUseVer==4)
- if (!testdma16(sbIRQ, sbDMA16))
- return 0;
- */
-
- plrSetOptions=sbSetOptions;
- plrPlay=sbPlay;
- plrStop=sbStop;
-
- return 1;
- }
-
- static void sbClose()
- {
- plrPlay=0;
- }
-
- static int sbDetect(deviceinfo &card)
- {
- getcfg();
- if (card.port!=-1)
- sbPort=card.port;
- if (card.irq!=-1)
- sbIRQ=card.irq;
- if (card.dma!=-1)
- sbDMA=card.dma;
- if (card.dma2!=-1)
- sbDMA16=card.dma2;
- if (card.subtype!=-1)
- sbUseVer=card.subtype;
-
- int i;
- if (sbPort==-1)
- {
- unsigned short ports[]={0x220, 0x240, 0x260, 0x280, 0x210, 0x230, 0x250};
- for (i=0; i<(sizeof(ports)>>1); i++)
- if (testPort(ports[i],0))
- break;
- if (i==(sizeof(ports)>>1))
- return 0;
- sbPort=ports[i];
- }
- else
- if (!testPort(sbPort, 0))
- return 0;
-
- unsigned short ver=getVersion()>>8;
- if (sbUseVer==-1)
- sbUseVer=ver;
- if ((sbUseVer<1)||(sbUseVer>4))
- return 0;
-
- if (ver<sbUseVer)
- return 0;
- if ((ver==4)&&(sbUseVer==3))
- return 0;
-
- if (sbIRQ==-1)
- {
- if (sbUseVer!=4)
- {
- unsigned char irqs[]={7, 5, 2, 3, 10};
- for (i=0; i<sizeof(irqs); i++)
- if (testirq(irqs[i]))
- break;
- if (i==sizeof(irqs))
- return 0;
- sbIRQ=irqs[i];
- }
- else
- {
- unsigned char a=readMixer(0x80);
- if (!(a&0x0F))
- return 0;
- sbIRQ=(a&2)?5:(a&4)?7:(a&1)?2:10;
- }
- }
- // else
- // if (!testirq(sbIRQ))
- // return 0;
-
- if (sbDMA==-1)
- {
- if (sbUseVer!=4)
- {
- unsigned char dmas[]={1, 0, 3};
- for (i=0; i<sizeof(dmas); i++)
- if (testdma(sbIRQ, dmas[i]))
- break;
- if (i==sizeof(dmas))
- return 0;
- sbDMA=dmas[i];
- }
- else
- {
- unsigned char b=readMixer(0x81);
- if (!(b&0x0B))
- return 0;
- sbDMA=(b&2)?1:(b&1)?0:3;
- }
- }
- // else
- // if (!testdma(sbIRQ, sbDMA))
- // return 0;
-
- if (sbUseVer==4)
- {
- if (sbDMA16==-1)
- {
- unsigned char b=readMixer(0x81);
- if (!(b&0x0B))
- return 0;
- sbDMA16=(b&0x20)?5:(b&0x40)?6:(b&0x80)?7:sbDMA;
- }
- // else
- // if (!testdma16(sbIRQ, sbDMA16))
- // return 0;
- }
- else
- sbDMA16=-1;
-
- card.dev=&plrSoundBlaster;
- card.port=sbPort;
- card.port2=-1;
- card.irq=sbIRQ;
- card.irq2=-1;
- card.dma=sbDMA;
- card.dma2=sbDMA16;
- card.subtype=sbUseVer;
- card.mem=0;
- card.chan=(card.subtype<3)?1:2;
-
- return 1;
- }
-
- extern "C" sounddevice plrSoundBlaster={SS_PLAYER, "SoundBlaster", sbDetect, sbInit, sbClose};
-
- #include "devigen.h"
- #include "psetting.h"
-
- static unsigned long sbGetOpt(const char *sec)
- {
- unsigned long opt=0;
- if (cfGetProfileBool(sec, "sbrevstereo", 0, 0))
- opt|=SS_SB_REVSTEREO;
- return opt;
- }
-
- extern "C" devaddstruct plrSBAdd = {sbGetOpt, 0, 0, 0};
-